﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataModel
{
    public class SiteColumn
    {
        /// <summary>
        /// The default SharePoint site column groups
        /// </summary>
        public static List<String> SiteColumnGroups = new List<String>(
            new[] {
            "Base Columns",
            "Content Feedback",
            "Core Contact and Calendar Columns",
            "Core document Columns",
            "Core Task and Issue Columns",
            "Custom Columns",
            "Display Template Columns",
            "Document and Record Management Columns",
            "Enterprise Keywords Group",
            "Extended Columns",
            "JavaScript Display and Template Columns",
            "Reports",
            "Status Indicators" 
        });   
        
        private String id;
        private String name;
        private String internalName;
        private String desc;
        private SiteColumnType type;
        private bool required;
        private bool unique;
        private String defaultVal;
        private String sampleVal;
        private List<String> sList;
        private String putInto;
        private object tag;
        private string typeDisplayName;

        public bool IsFromDump = false;

        public String ID { get { return id; } set { } }
        public String Name { get { return name; } set { name = value; } }
        public String InternalName { get { return internalName; } set { internalName = value; } }
        public String Desc { get { return desc; } set { desc = value; } }
        public SiteColumnType Type { get { return type; } set { type = value; } }
        public bool Required { get { return required; } set { required = value;  } }
        public bool Unique { get { return unique; } set { unique = value; } }
        public String DefaultVal { get { return defaultVal; } set { defaultVal = value; } }
        public String SampleVal { get { return sampleVal; } set { sampleVal = value; } }
        public List<String> SList { get { return sList; } set { } }
        public String PutInto { get { return putInto; } set { putInto = value; } }
        public object Tag { get { return tag; } set { tag = value; } }


        /// <summary>
        /// Gets or sets the display name of the type. If this has not been manually set, or is blank, it will return the Long Name of the SiteColumnType.
        /// </summary>
        /// <value>
        /// The display name of the type.
        /// </value>
        public String TypeDisplayName
        {
            get 
            {
                if (typeDisplayName != null && typeDisplayName != "")
                {
                    return typeDisplayName;
                }
                else
                {
                    return Type.ToString();
                }
            }
            set { typeDisplayName = value; }
        }

        /// <summary>
        /// The additional attributes
        /// </summary>
        public Dictionary<SiteColumnType, Dictionary<String, String>> additionalAttributes = new Dictionary<SiteColumnType, Dictionary<string, string>>();

        public String AdditionInfoImageSource
        {
            get
            {
                try
                {
                    if (this.type == SiteColumnType.MANAGED_METADATA && !((Term)this.tag).hasChildren())
                    {
                        return "ico/error.png";
                    }
                    else
                    {
                        return "ico/info.png";
                    }
                }
                catch (Exception ex)
                {
                    Log.Append("SiteColumn AdditionalInfoImageSource Exception: ").Append(ex.Message).AppendLine();
                    return "ico/info.png";
                }
            }
            set
            {

            }
        }
        public double AdditionalInfoOpacity
        {
            get
            {
                return (AdditionalInfoForToolTip == "No additional information available."
                    || AdditionalInfoForToolTip == "") ? 0.5 : 1.0;
            }
            set
            {

            }
        }
        public String AdditionalInfoForToolTip
        {
            get
            {
                StringBuilder s = new StringBuilder();
                try
                {
                    if (this.Type == SiteColumnType.CHOICE && this.sList.Count > 0)
                    {
                        s.Append("~~Available Choices:").AppendLine();
                        foreach (String str in this.sList)
                        {
                            s.AppendLine(str);
                        }
                    }
                    else if (this.Type == SiteColumnType.MANAGED_METADATA)
                    {
                        String flatChildren = ((TermSet)this.Tag).GetChildrenFlat();
                        if (flatChildren != "")
                        {
                            s.Append("Associated Term: ").Append(((TermSet)this.Tag).Name).AppendLine();
                            s.Append("~~Valid tags:").AppendLine();
                            s.AppendLine(flatChildren);
                        }
                    }
                    else
                    {
                        s.Append("No additional information available.");
                    }
                }
                catch (Exception ex)
                {
                    Log.Append("SiteColumn AdditionalInfoForToolTip exception: ").Append(ex.Message).AppendLine();
                }
                return s.ToString();
            }
            set { }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SiteColumn"/> class.
        /// </summary>
        /// <param name="id">The guid.</param>
        /// <param name="name">The name.</param>
        /// <param name="internalName">The internal name.</param>
        /// <param name="type">The type.</param>
        /// <param name="required">if set to <c>true</c> [required].</param>
        /// <param name="unique">if set to <c>true</c> [unique].</param>
        /// <param name="defaultVal">The default value.</param>
        /// <param name="sampleVal">The sample value.</param>
        /// <param name="desc">The description.</param>
        /// <param name="putInto">The group.</param>
        public SiteColumn(String id, String name, String internalName, SiteColumnType type, bool required = false, bool unique = false, String defaultVal = "", String sampleVal = "", String desc = "", String putInto = "Custom Columns")
        {
            this.id = id;
            this.name = name;
            this.internalName = internalName;
            this.desc = desc;
            this.type = type;
            this.required = required;
            this.unique = unique;
            this.defaultVal = defaultVal;
            this.sampleVal = sampleVal;
            sList = new List<String>();
            this.putInto = putInto;
            tag = null;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SiteColumn"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="internalName">The internal name.</param>
        public SiteColumn(String name, String internalName)
        {
            id = GUID.get();
            this.name = name;
            this.internalName = internalName;
            desc = "";
            type = SiteColumnType.SINGLE_LINE_OF_TEXT;
            required = false;
            unique = false;
            defaultVal = "";
            sampleVal = "";
            sList = new List<String>();
            putInto = "Custom Columns";
            tag = null;
        }

        public void RemoveReferences(ContentTypeList ctl)
        {
            List<ContentType> refList = new List<ContentType>();
            foreach (ContentType ct in ctl)
            {
                if (ct.SCList.Contains(this))
                {
                    refList.Add(ct);
                }
            }

            foreach (ContentType ct in refList)
            {
                ct.SCList.Remove(this);
            }
        }
    }
}
